package com.alibaba.cirtus.ots.application.app.ability.facade.v2serviceimpl;

import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.util.CalculatePercentage;
import com.alibaba.citrus.ots.sales.plan.model.SalesPlanReportAuditStatusEnum;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanLineSDO;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.*;
import com.epoch.app.bcorder.service.PlatformEnhanceService;
import com.epoch.app.bcorder.service.SalesPlanService;
import com.epoch.app.otsapplicationappsdk.monthplandetail.dto.*;
import com.epoch.app.otsapplicationappsdk.monthplandetail.service.MonthPlanDetailService;
import com.epoch.app.crplatformenhance.model.dto.CustomerAddressIndex;
import com.epoch.app.crplatformenhance.opecustomeraddressindex.dto.PageQueryCustomerAddressRequest;
import com.epoch.app.crplatformenhance.opecustomeraddressindex.dto.PageQueryCustomerAddressResponse;
import com.epoch.app.crplatformenhance.opecustomeraddressindex.service.OpeCustomerAddressIndexService;
import com.epoch.app.crunifiedinventory.model.dto.BusinessInventoryDTO;
import com.epoch.app.crunifiedinventory.model.dto.SearchBusinessInventoryByPageRequest;
import com.epoch.app.crunifiedinventory.service.StockManageService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chenlx
 */
@Service
public class MonthPlanDetailV2ServiceImpl implements MonthPlanDetailService {
    private static final Log log = Log.getLogger(MonthPlanDetailV2ServiceImpl.class);

    private static final String PLAN_ID = "planId";
    private static final String ADDRESS_ID = "addressId";
    private static final int DEFAULT_PAGE_SIZE = 1000;
    private static final String ERROR_CODE_1 = "param is null";
    private static final String ERROR_CODE_2 = "param {} is null";
    private static final String SYSTEM_ERROR = "system error";
    private static final long SLEEP_TIME = 1500;


    @Autowired
    SalesPlanService salesPlanService;

    @Autowired
    OpeCustomerAddressIndexService opeCustomerAddressIndexService;

    @Autowired
    PlatformEnhanceService platformEnhanceService;

    @Autowired
    StockManageService stockManageService;

    @Override
    @FacadeInvoker
    public Object render(RenderRequest renderRequest) {
        JSONObject result = new JSONObject();
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(renderRequest.getRequestBody()));
        if (jsonObject == null) {
            return null;
        }
        long t6 = System.currentTimeMillis();
        try {
            String planId = jsonObject.getString(PLAN_ID);
            String addressId = jsonObject.getString(ADDRESS_ID);
            String addressCode = jsonObject.getString("addressCode");
            if (StringUtils.isBlank(planId) || StringUtils.isBlank(addressId)) {
                throw new Exception("缺失必要参数");
            }
            SalesPlanSDO salesPlan = getSalesPlan(planId);
            boolean isPublished = salesPlan != null && salesPlan.getStatus() != null && salesPlan.getStatus() > 3;
            result.put("isPublished", isPublished);
            result.put("editable", isEditable(salesPlan));
            result.put(PLAN_ID, planId);
            result.put("addressCode", addressCode);
            result.put(ADDRESS_ID, addressId);
            //head
            CustomerAddressIndex customerAddressIndex = getHead(result, planId, addressId, addressCode);
            //计划货品范围迭代优化 - 取业务渠道
            String orgSalesChannelCode = customerAddressIndex != null ? customerAddressIndex.getChannelCode() : null;
            //查询明细
            Map<String, PlanLine> planScItemNumMap = getPlanLineList(result, planId, addressId, isPublished);
            //查询货品
            List<SalesPlanScItemSDO> scItemList = getScItemSDOS(planId, orgSalesChannelCode,addressCode,addressId,customerAddressIndex.getOrgSaleOrganizationCode());
            //查询货品类目
            Map<String, List<SalesPlanScItemSDO>> categoryItemMap = scItemList.stream()
                    .filter(scItem -> StringUtils.isNotBlank(scItem.getScItemLeafCategoryId()))
                    .collect(Collectors.groupingBy(SalesPlanScItemSDO::getScItemLeafCategoryId));
            List<String> categoryIdList = Lists.newArrayList(categoryItemMap.keySet());
            BatchQueryCategoryInfoRequest batchQueryCategoryInfoRequest = BatchQueryCategoryInfoRequest.builder()
                    .categoryIdList(categoryIdList)
                    .build();
            Object categoryResponse = platformEnhanceService.batchQueryCategoryInfo(batchQueryCategoryInfoRequest);
            List<Category> categorySDOList = Lists.newArrayList();
            if (categoryResponse != null) {
                JSONObject object = JSONObject.parseObject(JSON.toJSONString(categoryResponse));
                if (object.getBooleanValue("success") && object.getJSONObject("result") != null
                        && !CollectionUtils.isEmpty(object.getJSONObject("result").getJSONArray("categorySDOList"))) {
                    categorySDOList = object.getJSONObject("result").getJSONArray("categorySDOList").toJavaList(Category.class);
                }
            }
            List<String> categoryIds = categorySDOList.stream().map(Category::getCategoryId).collect(Collectors.toList());
            List<SalesPlanScItemSDO> scItemSDOList1 = scItemList.stream().filter(scItem ->
                    StringUtils.isBlank(scItem.getScItemLeafCategoryId())
                            || !categoryIds.contains(scItem.getScItemLeafCategoryId())).collect(Collectors.toList());
            JSONArray categoryArr = new JSONArray();

            for (Category category : categorySDOList) {
                String categoryId = category.getCategoryId();
                String categoryName = category.getCategoryName();
                if (categoryId == null || categoryName == null) {
                    continue;
                }
                List<SalesPlanScItemSDO> scItemSDOList = categoryItemMap.get(categoryId);
                JSONObject categoryGood = handleCategory(planScItemNumMap, categoryId, categoryName, scItemSDOList);
                categoryArr.add(categoryGood);
            }
            if (!CollectionUtils.isEmpty(scItemSDOList1)) {
                categoryArr.add(handleCategory(planScItemNumMap, "", "其他", scItemSDOList1));
            }
            result.put("goodsList", categoryArr);
            result.put("success", true);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", e.getMessage());
        }
        return result;
    }

    private boolean isEditable(SalesPlanSDO salesPlanSDO) {
        if (salesPlanSDO != null) {
            Integer status = salesPlanSDO.getStatus();
            Integer auditStatus = salesPlanSDO.getAuditStatus();
            return (status != null && status <= 3) &&
                    (auditStatus == null || !(SalesPlanReportAuditStatusEnum.UNDER_REVIEW.getCode() == auditStatus
                            || SalesPlanReportAuditStatusEnum.APPROVED.getCode() == auditStatus));
        }
        return false;
    }

    private SalesPlanSDO getSalesPlan(String planId) {
        PageQuerySalePlanListRequest request = new PageQuerySalePlanListRequest();
        request.setStart(0);
        request.setLimit(10);
        request.setId(planId);
        PageQuerySalePlanListResponse response = salesPlanService.pageQuerySalePlanList(request);
        if (response != null && response.getSuccess() && !CollectionUtils.isEmpty(response.getResult())) {
            return JSONObject.parseObject(JSON.toJSONString(response.getResult().get(0)), SalesPlanSDO.class);
        }
        return null;
    }

    private List<SalesPlanScItemSDO> getScItemSDOS(String planId, String orgSalesChannelCode,String addressCode,String addressId,String orgSalesOrganizationCode) throws Exception {
        PageQueryScItemSalesPlanLineResponse scItemSalesPlanLineResponse =
                getPlanLineResponse(1, DEFAULT_PAGE_SIZE, planId, orgSalesChannelCode,addressCode,addressId,orgSalesOrganizationCode);

        List<SalesPlanScItemSDO> scItemList = Lists.newArrayList();
        if (scItemSalesPlanLineResponse != null && !CollectionUtils.isEmpty(scItemSalesPlanLineResponse.getResult())) {
            scItemList.addAll(scItemSalesPlanLineResponse.getResult());
            if (scItemSalesPlanLineResponse.getTotal() > DEFAULT_PAGE_SIZE) {
                int scItemTotalPage = scItemSalesPlanLineResponse.getTotal() / DEFAULT_PAGE_SIZE;
                if (scItemSalesPlanLineResponse.getTotal() % DEFAULT_PAGE_SIZE > 0) {
                    scItemTotalPage++;
                }
                for (int i = 2; i <= scItemTotalPage; i++) {
                    PageQueryScItemSalesPlanLineResponse planLineResponse = getPlanLineResponse(i, DEFAULT_PAGE_SIZE, planId, orgSalesChannelCode,addressCode,addressId,orgSalesOrganizationCode);
                    if (planLineResponse != null && planLineResponse.getSuccess() && !CollectionUtils.isEmpty(planLineResponse.getResult())) {
                        scItemList.addAll(planLineResponse.getResult());
                    }
                }

            }
        }
        return scItemList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(SalesPlanScItemSDO::getScItemId))), ArrayList::new));
    }

    private JSONObject handleCategory(Map<String, PlanLine> planScItemNumMap, String categoryId, String categoryName, List<SalesPlanScItemSDO> scItemSDOList) {
        JSONObject categoryGood = new JSONObject();
        categoryGood.put("categoryId", categoryId);
        categoryGood.put("categoryTitle", categoryName);
        List<PlanLine> goodsList = scItemSDOList.stream().map(scItem -> {
            PlanLine planLine = (MapUtils.isEmpty(planScItemNumMap)
                    || !planScItemNumMap.containsKey(scItem.getScItemId())) ? null : planScItemNumMap.get(scItem.getScItemId());
            return PlanLine.builder()
                    .detailId(planLine == null ? null : planLine.getDetailId())
                    .id(scItem.getScItemId())
                    .goodsName(scItem.getScItemName())
                    .unit(scItem.getBasicUnit())
                    .goodsCode(scItem.getOuterId())
                    .goodsNum(0)
                    .scItemGroup(scItem.getScItemGroup())
                    .scItemLeafCategoryId(scItem.getScItemLeafCategoryId())
                    .scItemRootCategoryId(scItem.getScItemRootCategoryId())
                    .outboundPrice(scItem.getOutboundPrice())
                    .costInsuranceFreight(scItem.getCostInsuranceFreight())
                    .build();
        }).collect(Collectors.toList());
        categoryGood.put("goodsList", goodsList);
        return categoryGood;
    }

    private Map<String, Long> getStoreMap(String addressCode, List<String> scItemIdList) {
        PageQueryCustomerAddressResponse addressResponse = getCustomerAddress(0, DEFAULT_PAGE_SIZE, addressCode);
        if (addressResponse == null || CollectionUtils.isEmpty(addressResponse.getResult()) || CollectionUtils.isEmpty(scItemIdList)) {
            return null;
        }
        List<CustomerAddressIndex> customerAddressIndexList = addressResponse.getResult();
        if (addressResponse.getTotal() > DEFAULT_PAGE_SIZE) {
            int totalPage = addressResponse.getTotal() / DEFAULT_PAGE_SIZE;
            if (addressResponse.getTotal() % DEFAULT_PAGE_SIZE > 0) {
                totalPage++;
            }
            for (int i = 2; i <= totalPage; i++) {
                PageQueryCustomerAddressResponse customerAddressResponse = getCustomerAddress((i - 1) * DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE, addressCode);
                if (customerAddressResponse != null && !CollectionUtils.isEmpty(customerAddressResponse.getResult())) {
                    customerAddressIndexList.addAll(customerAddressResponse.getResult());
                }
            }
        }
        List<String> addressCodeList = customerAddressIndexList
                .stream()
                .map(CustomerAddressIndex::getAddressCode)
                .collect(Collectors.toList());
        SearchBusinessInventoryByPageRequest inventoryByPageRequest = SearchBusinessInventoryByPageRequest
                .builder()
                .addressCodeList(addressCodeList)
                .goodsIds(scItemIdList)
                .build();
        Result<List<BusinessInventoryDTO>> businessInventoryResult
                = stockManageService.searchBusinessInventoryByPage(inventoryByPageRequest);
        if (businessInventoryResult == null || CollectionUtils.isEmpty(businessInventoryResult.getResult())) {
            return null;
        }
        return businessInventoryResult.getResult()
                .stream()
                .collect(Collectors.groupingBy(BusinessInventoryDTO::getGoodsId,
                        Collectors.reducing(0L, BusinessInventoryDTO::getAvailableQuantity, Long::sum)));
    }

    @Override
    @FacadeInvoker
    public Object batchSavePlanLine(BatchSavePlanLineRequest batchSavePlanLineRequest) {
        Object requestBody = batchSavePlanLineRequest.getRequestBody();
        if (requestBody == null) {
            return Result.fail(ERROR_CODE_1, "批量保存月度计划详情入参为空");
        }
        JSONObject result = new JSONObject();
        try {
            JSONObject requestParam = JSONObject.parseObject(JSON.toJSONString(requestBody));
            String planId = requestParam.getString(PLAN_ID);
            String addressId = requestParam.getString(ADDRESS_ID);
            String addressCode = requestParam.getString("addressCode");
            JSONArray goodsChange = requestParam.getJSONArray("goodsChange");
            if (StringUtils.isBlank(planId)) {
                return Result.fail(ERROR_CODE_2, PLAN_ID);
            }
            if (StringUtils.isBlank(addressId)) {
                return Result.fail(ERROR_CODE_2, ADDRESS_ID);
            }

            QuerySalePlanInfoRequest planParam = new QuerySalePlanInfoRequest();
            planParam.setId(planId);
            QuerySalePlanInfoResponse planInfoResponse = salesPlanService.querySalePlanInfo(planParam);
            SalesPlanSDO salesPlan = planInfoResponse != null ? planInfoResponse.getResult() : null;
            boolean isPublished = salesPlan != null && salesPlan.getStatus() != null && salesPlan.getStatus() > 3;
            List<PlanLine> prePlanLines = queryPlanLines(planId, addressId, isPublished);


            List<PlanLine> planLines = goodsChange.toJavaList(PlanLine.class);
            List<PlanLine> addList = Lists.newArrayList();
            List<PlanLine> editList = Lists.newArrayList();
            getUpdateList(prePlanLines, planLines, addList, editList);
            List<PlanLine> deleteList = getDelList(prePlanLines, planLines);

            batchUpdatePlanLine(planId, addressId, addressCode, addList, editList, deleteList);
            JSONObject subTotal = getSubTotal(planId, addressCode, isPublished);
            if (subTotal != null) {
                result.put("beforeContractSatisfaction", subTotal.remove("beforeContractSatisfaction"));
                result.put("contractSatisfaction", subTotal.remove("contractSatisfaction"));
                result.put("subTotal", subTotal);
            }
            Thread.sleep(SLEEP_TIME);
            getPlanLineList(result, planId, addressId, isPublished);
            result.put("success", true);
        } catch (Exception e) {
            log.error("批量保存月度计划详情异常", e);
            result.put("success", false);
            result.put("message", e.getMessage());
        }
        return result;
    }

    @Transactional
    private void batchUpdatePlanLine(String planId, String addressId, String addressCode, List<PlanLine> addList, List<PlanLine> editList, List<PlanLine> deleteList) throws Exception {
        if (!CollectionUtils.isEmpty(addList)) {
            BatchCreateSalesPlanLineResponse addResult = addPlanList(addList, planId, addressId, addressCode);
            log.info("addResult:{}", JSON.toJSONString(addResult));
            if (addResult == null) {
                throw new Exception("批量新增月度计划详情异常");
            } else if (!addResult.getSuccess()) {
                throw new Exception(addResult.getMessage());
            }
        }
        if (!CollectionUtils.isEmpty(editList)) {
            editPlanList(editList, true);
        }
        if (!CollectionUtils.isEmpty(deleteList)) {
            DeleteSalesPlanLineResponse deleteSalesPlanLineResponse = deletePlanLineById(deleteList.stream()
                    .map(PlanLine::getDetailId).collect(Collectors.toList()));
            if (deleteSalesPlanLineResponse == null || !deleteSalesPlanLineResponse.getSuccess()) {
                String message = deleteSalesPlanLineResponse != null && StringUtils.isNotBlank(deleteSalesPlanLineResponse.getMessage())
                        ? deleteSalesPlanLineResponse.getMessage() : "批量删除月度计划明细异常";
                throw new Exception(message);
            }
        }
    }

    @Override
    @FacadeInvoker
    public Object savePlanLines(SavePlanLinesRequest savePlanLinesRequest) {
        Object requestBody = savePlanLinesRequest.getRequestBody();
        if (requestBody == null) {
            return Result.fail(ERROR_CODE_1, "保存月度计划明细入参为空");
        }
        try {
            JSONObject requestParam = JSONObject.parseObject(JSON.toJSONString(requestBody));
            String planId = requestParam.getString(PLAN_ID);
            if (StringUtils.isBlank(planId)) {
                return Result.fail(ERROR_CODE_2, PLAN_ID);
            }
            //计划汇总
            PlanStatServiceRequest planStatServiceRequest = PlanStatServiceRequest.builder().planId(planId).build();
            PlanStatServiceResponse planStatServiceResponse = salesPlanService.planStatService(planStatServiceRequest);
            if (planStatServiceResponse == null) {
                return Result.fail(null, "保存月度计划明细异常");
            }
            if (planStatServiceResponse.getSuccess()) {
                Thread.sleep(SLEEP_TIME);
                return Result.success(null);
            } else {
                return Result.fail(planStatServiceResponse.getErrorCode(), planStatServiceResponse.getMessage());
            }
        } catch (Exception e) {
            log.error("保存月度计划明细异常", e);
            return Result.fail(null, e.getMessage());
        }
    }

    private void getUpdateList(List<PlanLine> oldArrayList, List<PlanLine> newArrayList, List<PlanLine> addList, List<PlanLine> editList) {
        if (!CollectionUtils.isEmpty(newArrayList)) {
            if (!CollectionUtils.isEmpty(oldArrayList)) {
                for (PlanLine planLine : newArrayList) {
                    boolean isAdd = true;
                    boolean needEdit = false;
                    for (PlanLine prePlanLine : oldArrayList) {
                        if (prePlanLine.getId().equals(planLine.getId()) && prePlanLine.getDetailId().equals(planLine.getDetailId())) {
                            if (!prePlanLine.getGoodsNum().equals(planLine.getGoodsNum())) {
                                needEdit = true;
                            }
                            isAdd = false;
                            break;
                        }
                    }
                    if (isAdd) {
                        addList.add(planLine);
                    } else if (needEdit) {
                        editList.add(planLine);
                    }
                }
            } else if (!CollectionUtils.isEmpty(newArrayList)) {
                addList.addAll(newArrayList);
            }
        }
    }

    private List<PlanLine> getDelList(List<PlanLine> firstArrayList, List<PlanLine> secondArrayList) {
        return firstArrayList.stream()
                .filter(item -> !secondArrayList.stream().map(PlanLine::getId).collect(Collectors.toList()).contains(item.getId()))
                .collect(Collectors.toList());
    }

    @Override
    @FacadeInvoker
    public Object async(AsyncRequest asyncRequest) {
        JSONObject result = new JSONObject();
        Object requestBody = asyncRequest.getRequestBody();
        if (requestBody == null) {
            return Result.fail(ERROR_CODE_1, "查询月度计划详情入参为空");
        }
        try {
            JSONObject requestParam = JSONObject.parseObject(JSON.toJSONString(requestBody));
            String planId = requestParam.getString(PLAN_ID);
            String addressId = requestParam.getString(ADDRESS_ID);
            String addressCode = requestParam.getString("addressCode");
            if (StringUtils.isBlank(planId)) {
                return Result.fail(ERROR_CODE_2, PLAN_ID);
            }
            if (!StringUtils.isNumeric(planId)) {
                throw new Exception("planId入参有误");
            }
            if (StringUtils.isBlank(addressCode)) {
                return Result.fail(ERROR_CODE_2, "addressCode");
            }
            QuerySalePlanInfoRequest planParam = new QuerySalePlanInfoRequest();
            planParam.setId(planId);
            QuerySalePlanInfoResponse planInfoResponse = salesPlanService.querySalePlanInfo(planParam);
            boolean isPublished = planInfoResponse != null && planInfoResponse.getResult() != null && planInfoResponse.getResult().getStatus() != null && planInfoResponse.getResult().getStatus() > 3;
            JSONObject subTotal = getSubTotal(planId, addressCode, isPublished);
            if (subTotal != null) {
                result.put("beforeContractSatisfaction", subTotal.remove("beforeContractSatisfaction"));
                result.put("contractSatisfaction", subTotal.remove("contractSatisfaction"));
                result.put("subTotal", subTotal);
            }
            getPlanLineList(result, planId, addressId, isPublished);
            result.put("success", true);
        } catch (Exception e) {
            log.error("查询月度计划详情列表异常", e);
            result.put("success", false);
            result.put("message", "查询月度计划详情列表异常");
        }
        return result;
    }

    @Override
    @FacadeInvoker
    public Object updatePlanDetail(UpdatePlanDetailRequest updatePlanDetailRequest) {
        JSONObject result = new JSONObject();
        Object requestBody = updatePlanDetailRequest.getRequestBody();
        if (requestBody == null) {
            return Result.fail(ERROR_CODE_1, "保存月度计划明细入参为空");
        }
        try {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(requestBody));
            String planId = jsonObject.getString(PLAN_ID);
            String key = jsonObject.getString("key");
            String valueStr = jsonObject.getString("value");
            if (!StringUtils.isNumeric(valueStr)) {
                return Result.fail(ERROR_CODE_1, "请输入整数");
            }
            int value = Integer.parseInt(valueStr);
            JSONObject editDrawerItem = jsonObject.getJSONObject("editDrawerItem");
            if (StringUtils.isBlank(planId) || editDrawerItem == null) {
                return Result.fail(ERROR_CODE_1, "编辑月度计划详情入参为空");
            }
            PlanLine planLine = editDrawerItem.toJavaObject(PlanLine.class);
            EditSalesPlanLineRequest editSalesPlanLineRequest;
            if ("goodsNum".equals(key)) {
                editSalesPlanLineRequest = EditSalesPlanLineRequest
                        .builder()
                        .id(planLine.getDetailId())
                        .monthCount(value)
                        .isBalanced(true)
                        .build();
            } else {
                int monthFirstCount = "upPlan".equals(key) ? value : planLine.getUpPlan();
                int monthMiddleCount = "midPlan".equals(key) ? value : planLine.getMidPlan();
                int monthLastCount = "downPlan".equals(key) ? value : planLine.getDownPlan();
                editSalesPlanLineRequest = EditSalesPlanLineRequest
                        .builder()
                        .id(planLine.getDetailId())
                        .monthCount(monthFirstCount + monthMiddleCount + monthLastCount)
                        .monthFirstCount(monthFirstCount)
                        .monthMiddleCount(monthMiddleCount)
                        .monthLastCount(monthLastCount)
                        .isBalanced(false)
                        .build();
            }
            log.info("失焦保存月度计划明细param:" + JSON.toJSONString(editSalesPlanLineRequest));
            EditSalesPlanLineResponse editSalesPlanLineResponse = salesPlanService.editSalesPlanLine(editSalesPlanLineRequest);
            log.info("失焦保存月度计划明细result:" + JSON.toJSONString(editSalesPlanLineResponse));

            boolean isPublished = editSalesPlanLineResponse != null && editSalesPlanLineResponse.getResult() != null
                    && editSalesPlanLineResponse.getResult().getStatus() != null && editSalesPlanLineResponse.getResult().getStatus() > 3;
            if (editSalesPlanLineResponse != null && editSalesPlanLineResponse.getResult() != null) {
                PlanLine planLine1 = getPlanLine(editSalesPlanLineResponse.getResult(), isPublished);
                planLine1.setGoodsName(planLine.getGoodsName());
                planLine1.setStore(planLine.getStore());
                planLine1.setGoodsCode(planLine.getGoodsCode());
                result.put("editDrawerItem", planLine1);
            }
            result.put("success", true);
        } catch (Exception e) {
            log.error("保存月度计划明细异常", e.getMessage());
            return Result.fail(SYSTEM_ERROR, "保存月度计划明细异常");
        }
        return result;
    }

    @Override
    @FacadeInvoker
    public Object calculatePlanCount(CalculatePlanCountRequest calculatePlanCountRequest) {
        JSONObject result = new JSONObject();
        Object requestBody = calculatePlanCountRequest.getRequestBody();
        if (requestBody == null) {
            return Result.fail(ERROR_CODE_1, "计算计划量入参为空");
        }
        try {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(requestBody));
            String planId = jsonObject.getString(PLAN_ID);
            String key = jsonObject.getString("key");
            String valueStr = jsonObject.getString("value");
            if (!StringUtils.isNumeric(valueStr)) {
                return Result.fail(ERROR_CODE_1, "请输入整数");
            }
            int value = Integer.parseInt(valueStr);
            JSONObject editDrawerItem = jsonObject.getJSONObject("editDrawerItem");
            if (StringUtils.isBlank(planId) || editDrawerItem == null) {
                return Result.fail(ERROR_CODE_1, "计算计划量入参为空");
            }
            QuerySalePlanInfoResponse salePlanInfoResponse = salesPlanService.querySalePlanInfo(QuerySalePlanInfoRequest.builder().id(planId).build());
            if (salePlanInfoResponse == null || salePlanInfoResponse.getResult() == null) {
                return Result.fail(ERROR_CODE_1, "该月度计划不存在");
            }
            SalesPlanSDO salesPlanSDO = salePlanInfoResponse.getResult();
            PlanLine planLine = editDrawerItem.toJavaObject(PlanLine.class);

            calculate(salesPlanSDO, planLine, key, value);

            result.put("editDrawerItem", planLine);

            result.put("success", true);
        } catch (Exception e) {
            log.error("计算计划量异常", e);
            return Result.fail(SYSTEM_ERROR, "计算计划量异常");
        }
        return result;
    }

    @Override
    @FacadeInvoker
    public Object updatePlanLine(UpdatePlanLineRequest updatePlanLineRequest) {
        JSONObject result = new JSONObject();
        Object requestBody = updatePlanLineRequest.getRequestBody();
        if (requestBody == null) {
            return Result.fail(ERROR_CODE_1, "保存月度计划详情入参为空");
        }
        try {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(requestBody));
            String planId = jsonObject.getString(PLAN_ID);
            JSONObject editDrawerItem = jsonObject.getJSONObject("editDrawerItem");
            if (StringUtils.isBlank(planId) || editDrawerItem == null) {
                return Result.fail(ERROR_CODE_1, "保存月度计划详情入参为空");
            }
            PlanLine planLine = editDrawerItem.toJavaObject(PlanLine.class);
            EditSalesPlanLineRequest editSalesPlanLineRequest = EditSalesPlanLineRequest
                    .builder()
                    .id(planLine.getDetailId())
                    .monthFirstCount(planLine.getUpPlan())
                    .monthMiddleCount(planLine.getMidPlan())
                    .monthLastCount(planLine.getDownPlan())
                    .monthCount(planLine.getGoodsNum())
                    .isBalanced(false)
                    .build();
            log.info("失焦保存月度计划明细param:" + JSON.toJSONString(editSalesPlanLineRequest));
            EditSalesPlanLineResponse editSalesPlanLineResponse = salesPlanService.editSalesPlanLine(editSalesPlanLineRequest);
            log.info("失焦保存月度计划明细result:" + JSON.toJSONString(editSalesPlanLineResponse));
            if (editSalesPlanLineResponse == null) {
                return Result.fail(null, "保存月度计划明细异常");
            }
            if (!editSalesPlanLineResponse.getSuccess()) {
                return Result.fail(editSalesPlanLineResponse.getErrorCode(), editSalesPlanLineResponse.getMessage());
            }
            Thread.sleep(SLEEP_TIME);
        } catch (Exception e) {
            log.error("保存月度计划明细异常", e);
            return Result.fail(SYSTEM_ERROR, "保存月度计划明细异常");
        }
        return Result.success(null);
    }

    private void calculate(SalesPlanSDO salesPlan, PlanLine planLine, String key, Integer value) {
        boolean isBalanced = "goodsNum".equals(key);
        Integer goodsNum;

        int monthFirstCount;
        int monthMiddleCount;
        int monthLastCount;

        BigDecimal sum = salesPlan.getMonthFirstProprtion().add(salesPlan.getMonthMiddleProprtion()).add(salesPlan.getMonthLastProprtion());
        if (new BigDecimal(100).compareTo(sum) == 0) {
            //创建传总量需要三比均衡
            if (isBalanced) {
                goodsNum = value;
                //月度计划有配置三旬比例均衡
                //上旬计划量
                BigDecimal monthFirstProprtion = salesPlan.getMonthFirstProprtion();
                BigDecimal firstCount = monthFirstProprtion.multiply(new BigDecimal(goodsNum));
                monthFirstCount = firstCount.divide(new BigDecimal(100), 0, RoundingMode.DOWN).intValue();
                //下旬计划量
                BigDecimal monthLastProprtion = salesPlan.getMonthLastProprtion();
                BigDecimal LastCount = monthLastProprtion.multiply(new BigDecimal(goodsNum));
                monthLastCount = LastCount.divide(new BigDecimal(100), 0, RoundingMode.DOWN).intValue();
                //中旬计划量
                monthMiddleCount = goodsNum - (monthFirstCount + monthLastCount);
            } else {
                monthFirstCount = "upPlan".equals(key) ? value : planLine.getUpPlan();
                monthMiddleCount = "midPlan".equals(key) ? value : planLine.getMidPlan();
                monthLastCount = "downPlan".equals(key) ? value : planLine.getDownPlan();
                goodsNum = monthFirstCount + monthMiddleCount + monthLastCount;
            }
            planLine.setGoodsNum(goodsNum);
            planLine.setUpPlan(monthFirstCount);
            planLine.setMidPlan(monthMiddleCount);
            planLine.setDownPlan(monthLastCount);
            //计算折前计划金额
            long costInsuranceFreight = Objects.nonNull(planLine.getCostInsuranceFreight()) ? planLine.getCostInsuranceFreight() : 0;
            long beforeMonthMoney = goodsNum * costInsuranceFreight;
            planLine.setBeforeMonthMoney(formatAmount(beforeMonthMoney));
            //计算折后计划金额  折后计划金额=折前计划金额*(1-预估价格折扣率)
            BigDecimal multiply = salesPlan.getEstimateDiscount().divide(new BigDecimal(100), 2, RoundingMode.DOWN);
            BigDecimal subtract = new BigDecimal(1).subtract(multiply);
            Long monthMoney = new BigDecimal(beforeMonthMoney).multiply(subtract).longValue();
            planLine.setMonthMoney(formatAmount(monthMoney));
        }
    }

    @Override
    @FacadeInvoker
    public Object batchDelPlanLine(BatchDelPlanLineRequest batchDelPlanLineRequest) {
        Object requestBody = batchDelPlanLineRequest.getRequestBody();
        if (requestBody == null) {
            return Result.fail(ERROR_CODE_1, "查询月度计划详情入参为空");
        }
        try {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(requestBody));
            JSONArray planLineList = jsonObject.getJSONArray("salesPlanLineSDOList");
            if (planLineList != null && planLineList.size() > 0) {
                List<SalesPlanLineSDO> sdoList = planLineList.toJavaList(PlanLine.class).stream()
                        .map(planLine -> SalesPlanLineSDO.builder().id(planLine.getDetailId()).build()).collect(Collectors.toList());
                DeleteSalesPlanLineRequest request = DeleteSalesPlanLineRequest.builder()
                        .salesPlanLineSDOList(sdoList)
                        .build();
                DeleteSalesPlanLineResponse response = salesPlanService.deleteSalesPlanLine(request);
                if (response != null && response.getSuccess()) {
                    Thread.sleep(SLEEP_TIME);
                    return Result.listEmptySuccess();
                } else {
                    String message = response != null && StringUtils.isNotBlank(response.getMessage())
                            ? response.getMessage() : "批量删除月度计划明细异常";
                    return Result.fail(null, message);
                }
            } else {
                return Result.fail(ERROR_CODE_1, "未选择删除详情");
            }
        } catch (Exception e) {
            return Result.fail(ERROR_CODE_1, "未选择删除详情");
        }
//        return Result.listEmptySuccess();
    }


    private DeleteSalesPlanLineResponse deletePlanLineById(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return null;
        }
        List<SalesPlanLineSDO> salesPlanLineList = idList.stream()
                .map(id -> SalesPlanLineSDO.builder().id(id).build()).collect(Collectors.toList());
        DeleteSalesPlanLineRequest request = DeleteSalesPlanLineRequest.builder()
                .salesPlanLineSDOList(salesPlanLineList)
                .build();

        return salesPlanService.deleteSalesPlanLine(request);
    }

    private void editPlanList(List<PlanLine> editList, Boolean isBalance) throws Exception {
        if (CollectionUtils.isEmpty(editList)) {
            return;
        }
        for (PlanLine planLine : editList) {
            EditSalesPlanLineResponse editSalesPlanLineResponse = editPlanLine(isBalance, planLine);
            log.info("editSalesPlanLineResponse:{}", editSalesPlanLineResponse);
        }
    }

    private EditSalesPlanLineResponse editPlanLine(Boolean isBalance, PlanLine planLine) {
        EditSalesPlanLineRequest editSalesPlanLineRequest = EditSalesPlanLineRequest
                .builder()
                .id(planLine.getDetailId())
                .monthCount(planLine.getGoodsNum())
                .monthFirstCount(planLine.getUpPlan())
                .monthMiddleCount(planLine.getMidPlan())
                .monthLastCount(planLine.getDownPlan())
                .isBalanced(isBalance)
                .build();
        return salesPlanService.editSalesPlanLine(editSalesPlanLineRequest);
    }


    private BatchCreateSalesPlanLineResponse addPlanList(List<PlanLine> planLines, String planId, String
            addressId, String addressCode) throws Exception {
        PageQueryCustomerAddressResponse addressResponse = addressId == null
                ? getCustomerAddress(0, 10, addressCode)
                : getCustomerAddressById(addressId);
        if (addressResponse == null || CollectionUtils.isEmpty(addressResponse.getResult())) {
            throw new Exception("未查询到客户地址");
        }
        BatchCreateSalesPlanLineRequest request = BatchCreateSalesPlanLineRequest.builder()
                .salesPlanLineSDOList(convert2Param(planLines, planId, addressResponse.getResult().get(0))).build();
        return salesPlanService.batchCreateSalesPlanLine(request);
    }

    private List<SalesPlanLineSDO> convert2Param(List<PlanLine> planLines, String planId,
                                                 CustomerAddressIndex customerAddressSDO) {
        List<SalesPlanLineSDO> salesPlanLineSDOList = Lists.newArrayList();
        for (PlanLine planLine : planLines) {
            SalesPlanLineSDO salesPlanLineSDO = SalesPlanLineSDO.builder()
                    .channelCode(customerAddressSDO.getChannelCode())
                    .orgBusinessUnitCode(customerAddressSDO.getOrgBussinessUnitCode())
                    .orgSalesOrganizationCode(customerAddressSDO.getOrgSaleOrganizationCode())
                    .orgSalesChannelCode(customerAddressSDO.getOrgSaleChannelCode())
                    .orgSalesDepartmentCode(customerAddressSDO.getOrgSaleDepartmentCode())
                    .customerCode(customerAddressSDO.getCustomerCode())
                    .customerAddress(customerAddressSDO.getAddressCode())
                    .customerAddressId(customerAddressSDO.getId().toString())
                    .manageEmployeeId(customerAddressSDO.getPrincipal())
                    .scItemId(planLine.getId())
                    .scItemGroup(planLine.getScItemGroup())
                    .scItemLeafCategoryId(planLine.getScItemLeafCategoryId())
                    .scItemRootCategoryId(planLine.getScItemRootCategoryId())
                    .outboundPrice(planLine.getOutboundPrice())
                    .costInsuranceFreight(planLine.getCostInsuranceFreight())
                    .basicUnit(planLine.getUnit())
                    .outerId(planLine.getGoodsCode())
                    .build();
            salesPlanLineSDO.setMonthCount(planLine.getGoodsNum());
            salesPlanLineSDO.setPlanId(planId);
            salesPlanLineSDOList.add(salesPlanLineSDO);
        }
        return salesPlanLineSDOList;
    }


    private PageQueryScItemSalesPlanLineResponse getPlanLineResponse(int page, int size, String planId, String
            orgSalesChannelCode,String addressCode,String addressId,String orgSalesOrganizationCode) {
        PageQueryScItemSalesPlanLineRequest scItemSalesPlanLineRequest = new PageQueryScItemSalesPlanLineRequest();
        scItemSalesPlanLineRequest.setPlanId(planId);
        scItemSalesPlanLineRequest.setOrgBusinessChannelCode(orgSalesChannelCode);
        scItemSalesPlanLineRequest.setPage(page);
        scItemSalesPlanLineRequest.setSize(size);
        scItemSalesPlanLineRequest.setAddressCode(addressCode);
        scItemSalesPlanLineRequest.setAddressId(addressId);
        scItemSalesPlanLineRequest.setOrgSalesOrganizationCode(orgSalesOrganizationCode);
        log.info("查询计划货品参数 {} ",JSONObject.toJSONString(scItemSalesPlanLineRequest));
        return salesPlanService.pageQueryScItemSalesPlanLine(scItemSalesPlanLineRequest);
    }

    private Map<String, PlanLine> getPlanLineList(JSONObject result, String planId, String addressId, boolean isPublished) {
        JSONArray planLineArr = new JSONArray();
        JSONArray planLineArr2 = new JSONArray();
        List<PlanLine> planLineList = queryPlanLines(planId, addressId, isPublished);
        Map<String, PlanLine> planScItemNumMap = Maps.newHashMap();
        for (PlanLine planLine : planLineList) {
            Integer status = planLine.getStatus();
            if (status != null && status.equals(1)) {
                planLineArr2.add(planLine);
            }
            planLineArr.add(planLine);
            planScItemNumMap.put(planLine.getId(),
                    PlanLine.builder().goodsNum(planLine.getGoodsNum()).detailId(planLine.getDetailId()).build());
        }
        result.put("dataSource", planLineArr);
        result.put("filterSource", planLineArr2);
        return planScItemNumMap;
    }

    private List<PlanLine> queryPlanLines(String planId, String addressId, boolean isPublished) {
        List<Object> planLineList = Lists.newArrayList();
        PageQuerySalesPlanLineList2Request planLineListRequest = new PageQuerySalesPlanLineList2Request();
        planLineListRequest.setPage(1);
        planLineListRequest.setSize(DEFAULT_PAGE_SIZE);
        planLineListRequest.setPlanId(planId);
        planLineListRequest.setCustomerAddressId(addressId);
        PageQuerySalesPlanLineList2Response listResponse = salesPlanService.pageQuerySalesPlanLineList2(planLineListRequest);
        if (listResponse != null && listResponse.getSuccess() && !CollectionUtils.isEmpty(listResponse.getResult())) {
            planLineList.addAll(listResponse.getResult());
            if (listResponse.getTotal() > DEFAULT_PAGE_SIZE) {
                int totalPage = listResponse.getTotal() / DEFAULT_PAGE_SIZE;
                if (listResponse.getTotal() % DEFAULT_PAGE_SIZE > 0) {
                    totalPage++;
                }
                for (int i = 2; i <= totalPage; i++) {
                    planLineListRequest.setPage(i);
                    planLineListRequest.setSize(DEFAULT_PAGE_SIZE);
                    PageQuerySalesPlanLineList2Response pageResponse = salesPlanService.pageQuerySalesPlanLineList2(planLineListRequest);
                    if (pageResponse != null && pageResponse.getSuccess() && !CollectionUtils.isEmpty(pageResponse.getResult())) {
                        planLineList.addAll(pageResponse.getResult());
                    }
                }
            }
        }
        return planLineList.stream().map(o -> getPlanLine(o, isPublished)).collect(Collectors.toList());
    }

    private PlanLine getPlanLine(Object obj, boolean isPublished) {
        JSONObject planLineObj = JSONObject.parseObject(JSON.toJSONString(obj));
        String basicUnit = StringUtils.isNotBlank(planLineObj.getString("basicUnit")) ? "元/" + planLineObj.getString("basicUnit") : "元/件";
        String inventory = StringUtils.isNotBlank(planLineObj.getString("inventoryStr"))
                ?planLineObj.getString("inventoryStr")
                :"0";

        return PlanLine.builder()
                .detailId(planLineObj.getLong("id"))
                .id(planLineObj.getString("scItemId"))
                .goodsName(planLineObj.getString("scItemName"))
                .upPlan(isPublished ? planLineObj.getInteger("monthFirstTaskCount") : planLineObj.getInteger("monthFirstCount"))
                .midPlan(isPublished ? planLineObj.getInteger("monthMiddleTaskCount") : planLineObj.getInteger("monthMiddleCount"))
                .downPlan(isPublished ? planLineObj.getInteger("monthLastTaskCount") : planLineObj.getInteger("monthLastCount"))
                .store(inventory)
                .goodsCode(planLineObj.getString("outerId"))
                .goodsNum(isPublished ? planLineObj.getInteger("taskCount") : planLineObj.getInteger("monthCount"))
                .scItemGroup(planLineObj.getString("scItemGroup"))
                .scItemLeafCategoryId(planLineObj.getString("scItemLeafCategoryId"))
                .scItemRootCategoryId(planLineObj.getString("scItemRootCategoryId"))
                .outboundPrice(planLineObj.getLong("outboundPrice"))
                .costInsuranceFreight(planLineObj.getLong("costInsuranceFreight"))
                .price(fmtMicrometer(toYuanByFen(planLineObj.getLong("costInsuranceFreight")) + "") + basicUnit)
                .unit(planLineObj.getString("basicUnit"))
                .status(planLineObj.getInteger("status"))
                .monthContractCount(planLineObj.getInteger("monthContractCount"))
                .monthMoney(formatAmount(planLineObj.getLong("monthMoney")))
                .beforeMonthMoney(formatAmount(planLineObj.getLong("beforeMonthMoney")))
                .build();
    }

    private CustomerAddressIndex getHead(JSONObject result, String planId, String addressId, String addressCode) {
        PageQueryCustomerAddressResponse addressResponse = addressId == null
                ? getCustomerAddress(0, 10, addressCode)
                : getCustomerAddressById(addressId);
        CustomerAddressIndex customerAddress = null;
        if (addressResponse != null && !CollectionUtils.isEmpty(addressResponse.getResult())) {
            customerAddress = addressResponse.getResult().get(0);
            addressCode = customerAddress.getAddressCode();
            result.put("customerName", customerAddress.getAddressName());
            result.put("customerAddress", customerAddress.getAddress());
        }
        result.put("subTotal", getSubTotalSales(planId, addressCode));
        return customerAddress;
    }

    private JSONObject getSubTotal(String planId, String addressCode, boolean isPublished) {
        SalesPlanStatCustomerSDO subTotal = getSubTotalSales(planId, addressCode);
        if (subTotal == null) {
            return null;
        }
        int monthCount;
        long beforeMonthMoney;
        long monthMoney;
        if (isPublished) {
            monthCount = subTotal.getTaskCount() == null ? 0 : subTotal.getTaskCount();
            beforeMonthMoney = subTotal.getBeforeTaskMoney() == null ? 0L : subTotal.getBeforeTaskMoney();
            monthMoney = subTotal.getTaskMoney() == null ? 0L : subTotal.getTaskMoney();
        } else {
            monthCount = subTotal.getMonthCount() == null ? 0 : subTotal.getMonthCount();
            beforeMonthMoney = subTotal.getBeforeMonthMoney() == null ? 0L : subTotal.getBeforeMonthMoney();
            monthMoney = subTotal.getMonthMoney() == null ? 0L : subTotal.getMonthMoney();
        }
        int monthContractCount = subTotal.getMonthContractCount() == null ? 0 : subTotal.getMonthContractCount();
        long beforeMonthContractMoney = subTotal.getBeforeMonthContractMoney() == null ? 0L : subTotal.getBeforeMonthContractMoney();
        long monthContractMoney = subTotal.getMonthContractMoney() == null ? 0L : subTotal.getMonthContractMoney();

        String totalBasicUnit = "";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("monthCount", fmtMicrometer((monthCount + "")) + totalBasicUnit);
        jsonObject.put("beforeMonthMoney",  formatAmount(beforeMonthMoney));
        jsonObject.put("monthMoney",  formatAmount(monthMoney));
        jsonObject.put("monthContractCount", fmtMicrometer((monthContractCount + "")) + totalBasicUnit);
        jsonObject.put("beforeMonthContractMoney",  formatAmount(beforeMonthContractMoney));
        jsonObject.put("monthContractMoney", formatAmount(monthContractMoney));
        String beforeContractSatisfactionPer = "-%";
        if (beforeMonthMoney >= 0 && beforeMonthContractMoney > 0) {
            BigDecimal beforeContractSatisfaction = CalculatePercentage.retainTwo(beforeMonthMoney, beforeMonthContractMoney);
            beforeContractSatisfactionPer = fmtMicrometer(beforeContractSatisfaction + "") + "%";
        }
        String contractSatisfactionPer = "-%";
        if (monthMoney >= 0 && monthContractMoney > 0) {
            BigDecimal contractSatisfaction = CalculatePercentage.retainTwo(monthMoney, monthContractMoney);
            contractSatisfactionPer = fmtMicrometer(contractSatisfaction + "") + "%";
        }
        jsonObject.put("beforeContractSatisfaction", beforeContractSatisfactionPer);
        jsonObject.put("contractSatisfaction", contractSatisfactionPer);
        return jsonObject;
    }

    private SalesPlanStatCustomerSDO getSubTotalSales(String planId, String addressCode) {
        SalesPlanStatCustomerSDO subTotal = null;
        try {
            SubTotalSalesPlanLineRequest subTotalSalesPlanLineRequest =
                    SubTotalSalesPlanLineRequest.builder().planId(planId).customerAddress(addressCode).build();
            SubTotalSalesPlanLineResponse subTotalSalesPlanLineResponse = salesPlanService.subTotalSalesPlanLine(subTotalSalesPlanLineRequest);
            if (subTotalSalesPlanLineResponse != null
                    && subTotalSalesPlanLineResponse.getSuccess()
                    && subTotalSalesPlanLineResponse.getResult() != null) {
                subTotal = subTotalSalesPlanLineResponse.getResult();
            }
        } catch (Exception e) {
            log.error("查询月度计划明细小计异常", e);
        }
        return subTotal;
    }

    private PageQueryCustomerAddressResponse getCustomerAddressById(String addressId) {
        PageQueryCustomerAddressRequest planLineRequest = new PageQueryCustomerAddressRequest();
        planLineRequest.setIdList(Lists.newArrayList(addressId));
        planLineRequest.setLimit(1);
        planLineRequest.setStart(0);
        planLineRequest.setStatus(1);
        return opeCustomerAddressIndexService.pageQueryCustomerAddress(planLineRequest);
    }

    private PageQueryCustomerAddressResponse getCustomerAddress(Integer start, Integer limit, String addressCode) {
        PageQueryCustomerAddressRequest planLineRequest = new PageQueryCustomerAddressRequest();
        planLineRequest.setAddressCodeList(Lists.newArrayList(addressCode));
        planLineRequest.setLimit(limit);
        planLineRequest.setStart(start);
        planLineRequest.setStatus(1);
        return opeCustomerAddressIndexService.pageQueryCustomerAddress(planLineRequest);
    }

    @Builder
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class PlanLine {
        private String id;
        private Long detailId;
        private String goodsName;
        private String preGiv;
        private String store;
        private String unit;
        private String order;
        private String produceDate;
        private String goodsCode;
        private Integer goodsNum;
        private Integer upPlan;
        private Integer midPlan;
        private Integer downPlan;
        private String scItemGroup;
        private String scItemLeafCategoryId;
        private String scItemRootCategoryId;
        private Long outboundPrice;
        private Long costInsuranceFreight;
        private String price;
        private Integer status;
        private Integer monthContractCount;
        private String beforeMonthMoney;
        private String monthMoney;
    }

    @Builder
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Category {
        private String categoryId;
        private String categoryName;

    }

    private String formatAmount(Long money) {
        if (money == null) {
            return "";
        }
        //大于10万，单位为万元
        if (money > 10000000) {
            return new BigDecimal(money).divide(new BigDecimal(1000000), 2, RoundingMode.HALF_DOWN) + "万元";
        }
        return fmtMicrometer(new BigDecimal(money).divide(new BigDecimal(100), 2, RoundingMode.HALF_DOWN).toString()) + "元";
    }

    private BigDecimal toYuanByFen(Long price) {
        if (price == null) {
            return new BigDecimal(0);
        }
        return new BigDecimal(price).divide(new BigDecimal(100), 2, RoundingMode.DOWN);
    }

    private String fmtMicrometer(String text) {
        if (StringUtils.isBlank(text)) {
            return null;
        }
        DecimalFormat df;
        if (text.indexOf(".") > 0) {
            int index = text.length() - text.indexOf(".") - 1;
            if (index == 0) {
                df = new DecimalFormat("###,##0.");
            } else if (index == 1) {
                df = new DecimalFormat("###,##0.0");
            } else {
                df = new DecimalFormat("###,##0.00");
            }
        } else {
            df = new DecimalFormat("###,##0");
        }
        double number;
        try {
            number = Double.parseDouble(text);
        } catch (Exception e) {
            number = 0.0;
        }
        return df.format(number);
    }
}
